// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include "Components/GameStateComponent.h"

#include "LyraTeamCreationComponent.generated.h"

class ULyraExperienceDefinition;
class ALyraTeamPublicInfo;
class ALyraTeamPrivateInfo;
class ALyraPlayerState;
class AGameModeBase;
class APlayerController;
class ULyraTeamDisplayAsset;

UCLASS(Blueprintable)
class ULyraTeamCreationComponent : public UGameStateComponent
{
	GENERATED_BODY()

public:
	ULyraTeamCreationComponent(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get()); // 构造函数

	//~UObject接口
#if WITH_EDITOR
	virtual EDataValidationResult IsDataValid(class FDataValidationContext& Context) const override; // 数据验证
#endif
	//~UObject接口结束

	//~UActorComponent接口
	virtual void BeginPlay() override; // 开始播放
	//~UActorComponent接口结束

private:
	/**
	 * 当经验加载完成时调用
	 */
	void OnExperienceLoaded(const ULyraExperienceDefinition* Experience);

protected:
	// 要创建的团队列表（ID到显示资源的映射，如果需要可以留空显示资源）
	UPROPERTY(EditDefaultsOnly, Category = Teams)
	TMap<uint8, TObjectPtr<ULyraTeamDisplayAsset>> TeamsToCreate; // 要创建的团队映射

	UPROPERTY(EditDefaultsOnly, Category=Teams)
	TSubclassOf<ALyraTeamPublicInfo> PublicTeamInfoClass; // 公共团队信息类

	UPROPERTY(EditDefaultsOnly, Category=Teams)
	TSubclassOf<ALyraTeamPrivateInfo> PrivateTeamInfoClass; // 私有团队信息类

#if WITH_SERVER_CODE
protected:
	/**
	 * 服务器端创建团队
	 */
	virtual void ServerCreateTeams();

	/**
	 * 服务器端分配玩家到团队
	 */
	virtual void ServerAssignPlayersToTeams();

	/**
	 * 为给定玩家状态设置团队ID。仅观战的玩家状态将被剥离任何团队关联。
	 */
	virtual void ServerChooseTeamForPlayer(ALyraPlayerState* PS);

private:
	/**
	 * 当玩家初始化时调用
	 */
	void OnPlayerInitialized(AGameModeBase* GameMode, AController* NewPlayer);

	/**
	 * 服务器端创建团队
	 */
	void ServerCreateTeam(int32 TeamId, ULyraTeamDisplayAsset* DisplayAsset);

	/**
	 * 返回活跃玩家最少的团队ID，如果没有有效团队则返回INDEX_NONE
	 */
	int32 GetLeastPopulatedTeamID() const;
#endif
};